package com.scau.jansing.work;

import com.scau.jansing.util.CommonUtils;
import com.scau.jansing.util.FileUtils;
import org.junit.Test;

import java.io.File;
import java.io.FileOutputStream;
import java.io.IOException;
import java.lang.annotation.Annotation;
import java.lang.reflect.*;
import java.util.Arrays;
import java.util.HashMap;
import java.util.Iterator;
import java.util.Map;


/**
 * Created by jansing on 2015/10/7.
 */
public class testWork {

    //输出类名
//            System.out.println(personClass);                            //class com.scau.jansing.entities.Person
//            System.out.println(personClass.getName());                  //com.scau.jansing.entities.Person
//            System.out.println(personClass.getSimpleName());            //Person
//            System.out.println(personClass.getCanonicalName());         //com.scau.jansing.entities.Person


    //        Field[] fields = personClass.getDeclaredFields();
//        Field f = fields[6];
//            System.out.println(f);
//            System.out.println(f.getName());
//            System.out.println(f.getType());
//            System.out.println(f.getGenericType());
//            System.out.println(f.getClass());
//            System.out.println(f.getDeclaringClass());
//            System.out.println(f.getAnnotatedType());
        /*
private java.lang.String com.scau.jansing.entities.Person.idNo
idNo
class java.lang.String
class java.lang.String
class java.lang.reflect.Field
class com.scau.jansing.entities.Person
sun.reflect.annotation.AnnotatedTypeFactory$AnnotatedTypeBaseImpl@ba21f3
class java.lang.Object
         */

//        personClass.getAnnotations();
//    System.out.println(personClass.getAnnotatedInterfaces());
//    System.out.println(personClass.getAnnotatedSuperclass().getType());
//    System.out.println(personClass.getAnnotations());
//    System.out.println(personClass.getDeclaredAnnotations());
//    System.out.println(personClass.getDeclaredClasses());
//    System.out.println(personClass.getGenericInterfaces());       //java.io.Serializable
//    System.out.println(personClass.getInterfaces());              //java.io.Serializable
//    System.out.println(personClass.getGenericSuperclass());     //class java.lang.Object
//    System.out.println(personClass.getTypeName());              //com.scau.jansing.entities.Person
//    System.out.println(personClass.getTypeParameters());
//    System.out.println(personClass.getSuperclass());            //class java.lang.Object


    @Test
    public void test01() throws ClassNotFoundException, IllegalAccessException, InstantiationException {

        Class personClass = Class.forName("com.scau.jansing.entities.Person");

        for (Annotation c : personClass.getDeclaredAnnotations()) {
            //得到声明的注解信息
            System.out.println("-------------------");
//        System.out.println(c);
            //@com.scau.jansing.util.ClassAtInterface(value=fff, t1=t1, num=-1)
            String annotation = c.toString();
            String annotationDeclare = annotation.substring(0, annotation.indexOf("("));
            System.out.println(annotationDeclare);
            //@com.scau.jansing.util.ClassAtInterface

            //得到声明的属性值
            Map<String, String> paramsMap = new HashMap<>();
            String annotationParams = annotation.substring(annotation.indexOf("(") + 1, annotation.length() - 1);
            System.out.println(annotationParams);
            //value=fff, t1=t1, num=-1

            String[] annotationParamsKeyValue = annotationParams.split(",");
            for (String keyValueString : annotationParamsKeyValue) {
                System.out.println(keyValueString.trim());
                String[] temp1 = keyValueString.split("=");
                String key = temp1[0];
                String value = temp1[1];
                System.out.println(key.trim() + "  ---  " + value.trim());
                paramsMap.put(key.trim(), value.trim());
//            BeanUtils.copyProperty();
            /*
value=fff
value  ---  fff
t1=t1
t1  ---  t1value
num=-1
num  ---  -1
             */
            }


            //得到接口类默认信息
            Class annotationClassDefault = Class.forName(c.annotationType().getName());

            Method[] methods = annotationClassDefault.getDeclaredMethods();
            StringBuilder paramStringBuilder = new StringBuilder();
            for (Method m : methods) {
                if (paramsMap.get(m.getName()) != null) {
                    System.out.println("===================");
                    System.out.println(m.getName() + " --- " + paramsMap.get(m.getName()).equals(m.getDefaultValue().toString()));
                    if (!paramsMap.get(m.getName()).equals(m.getDefaultValue().toString())) {
                        if (paramStringBuilder.length() != 0) {
                            paramStringBuilder.append(", ");
                        }
                        paramStringBuilder.append(m.getName()).append(" = ")
                                .append(CommonUtils.getDeclareValue(m.getGenericReturnType().getTypeName(), paramsMap.get(m.getName())));
                    }
                }
            }
            if (paramStringBuilder.length() > 0) {
                paramStringBuilder.insert(0, "(").append(")");
            }
            paramStringBuilder.insert(0, annotationDeclare);
            System.out.println(paramStringBuilder);


//        System.out.println(int.class);
//        System.out.println(boolean.class);
//        System.out.println(double.class);
        /*
        int
        boolean
        double
         */


        }
    }


    @Test
    public void test02() throws ClassNotFoundException {
        Class annotationClazz = Class.forName("com.scau.jansing.util.ClassAtInterface");
        Method f = annotationClazz.getDeclaredMethods()[1];
        System.out.println(Modifier.toString(f.getModifiers()) + " " + f.getGenericReturnType() + " " + f.getName());
        System.out.println(f.getDefaultValue());
        //public abstract class java.lang.String value
    }

    /**
     * 不改变原来的值
     */
    @Test
    public void test03() {
        String s = "asdfgh";
        String ss = s.replaceFirst("a", "123");
        System.out.println(ss);

        String src = "ab43a2c43d";
        System.out.println(src.replace("3", "f"));
        System.out.println(src.replace('3', 'f'));
        System.out.println(src.replaceAll("\\d", "f"));
        System.out.println(src.replaceAll("a", "f"));
        System.out.println(src.replaceFirst("\\d", "f"));
        System.out.println(src.replaceFirst("4", "h"));
        /**
         *   ab43a2c43d
         abffafcffd
         fb43f2c43d
         abf3a2c43d
         abh3a2c43d
         */
    }

    @Test
    public void test04() throws ClassNotFoundException {
        Class personClass = Class.forName("com.scau.jansing.entities.Person");
        Constructor constructor = personClass.getConstructors()[0];

        for (Annotation c : constructor.getDeclaredAnnotations()) {
            System.out.println(c);
//            @com.scau.jansing.util.MethodAtInterface(value=CONSTRUCTOR)

            String annotation = c.toString();
            String annotationDeclare = annotation.substring(0, annotation.indexOf("("));

            //得到声明的属性值
            Map<String, String> paramsMap = new HashMap<>();
            String annotationParams = annotation.substring(annotation.indexOf("(") + 1, annotation.length() - 1);

            String[] annotationParamsKeyValue = annotationParams.split(",");
            for (String keyValueString : annotationParamsKeyValue) {
                String[] temp1 = keyValueString.split("=");
                String key = temp1[0];
                String value = temp1[1];
                System.out.println(keyValueString.trim());
                System.out.println(key.trim() + "  ---  " + value.trim());
                paramsMap.put(key.trim(), value.trim());
            }

            //得到接口类默认信息
            Class annotationClassDefault = Class.forName(c.annotationType().getName());

            Method[] methods = annotationClassDefault.getDeclaredMethods();
            StringBuilder paramStringBuilder = new StringBuilder();
            for (Method m : methods) {
                if (paramsMap.get(m.getName()) != null) {
                    System.out.println("===================");
                    System.out.println(m.getName() + " --- " + paramsMap.get(m.getName()).equals(m.getDefaultValue().toString()));
                    if (!paramsMap.get(m.getName()).equals(m.getDefaultValue().toString())) {
                        if (paramStringBuilder.length() != 0) {
                            paramStringBuilder.append(", ");
                        }
                        paramStringBuilder.append(m.getName()).append(" = ")
                                .append(CommonUtils.getDeclareValue(m.getGenericReturnType().getTypeName(), paramsMap.get(m.getName())));
                    }
                }
                if (paramStringBuilder.length() > 0) {
                    paramStringBuilder.insert(0, "(").append(")");
                }
                paramStringBuilder.insert(0, annotationDeclare);
                System.out.println(paramStringBuilder);
            }
        }
    }

    @Test
    public void test05() throws ClassNotFoundException {
        Class personClass = Class.forName("com.scau.jansing.entities.Person");
        Constructor constructor = personClass.getConstructors()[0];
        Iterator<Annotation> annotationIterator = Arrays.asList(constructor.getDeclaredAnnotations()).iterator();
        while (annotationIterator.hasNext())
            System.out.println(CommonUtils.getClassDeclareAnnotation(annotationIterator.next()));
    }

    @Test
    public void test06() throws ClassNotFoundException {
        StringBuilder temp = new StringBuilder();
        Class personClass = Class.forName("com.scau.jansing.entities.Person");
        Iterator<Constructor> constructorIterator = Arrays.asList(personClass.getConstructors()).iterator();
        while (constructorIterator.hasNext()) {
            Constructor constructor = constructorIterator.next();
            //得到注解
            Iterator<Annotation> annotationIterator = Arrays.asList(constructor.getDeclaredAnnotations()).iterator();
            while (annotationIterator.hasNext())
                temp.append(CommonUtils.getTab(1))
                        .append(CommonUtils.getClassDeclareAnnotation(annotationIterator.next())).append("\n");

            temp.append(CommonUtils.getTab(1))
                    .append(Modifier.toString(constructor.getModifiers())).append(" ")
                    .append(personClass.getSimpleName()).append("(");


            Class[] paramsClass = constructor.getParameterTypes();
            for (int i = 0; i < paramsClass.length; i++) {
                if (i != 0) {
                    temp.append(", ");
                }
                temp.append(paramsClass[i].getName()).append(" param").append(i);
            }
            temp.append(")");

            //获得异常
            Iterator<Type> exceptionIterator = Arrays.asList(constructor.getGenericExceptionTypes()).iterator();
            if (exceptionIterator.hasNext()) {
                temp.append(" throws ").append(exceptionIterator.next().getTypeName());
            }
            while (exceptionIterator.hasNext()) {
                temp.append(", ").append(exceptionIterator.next().getTypeName());
            }


            temp.append(" {\n");
            temp.append(CommonUtils.getTab(1)).append("}\n\n");
        }
        System.out.println(temp);
    }

    @Test
    public void test07() throws ClassNotFoundException {
        Class personClass = Class.forName("com.scau.jansing.entities.Person");
        Iterator<Constructor> constructorIterator = Arrays.asList(personClass.getConstructors()).iterator();
        while (constructorIterator.hasNext()) {
            System.out.println("--------------------------------------");
            Constructor con = constructorIterator.next();
            System.out.println(CommonUtils.getConstructor(con));
        }
    }

    @Test
    public void test08() throws ClassNotFoundException {
        StringBuilder temp = new StringBuilder();
        Class personClass = Class.forName("com.scau.jansing.entities.Person");
        Iterator<Method> methodIterator = Arrays.asList(personClass.getDeclaredMethods()).iterator();

        while(methodIterator.hasNext()){
            Method method = methodIterator.next();
            Iterator<Annotation> annotationIterator = Arrays.asList(method.getDeclaredAnnotations()).iterator();
            while(annotationIterator.hasNext())
                temp.append(CommonUtils.getTab(1))
                        .append(CommonUtils.getClassDeclareAnnotation(annotationIterator.next())).append("\n");

            //得到方法
            temp.append(CommonUtils.getTab(1))
                    .append(Modifier.toString(method.getModifiers())).append(" ")
                    .append(method.getGenericReturnType().getTypeName()).append(" ")
                    .append(method.getName()).append("(")
                    //获得参数
                    .append(CommonUtils.getParameterString(method.getParameterTypes())).append(")")
                    //获得异常
                    .append(CommonUtils.getExceptionString(method.getGenericExceptionTypes())).append(" {\n")
                    .append(CommonUtils.getTab(1)).append("}\n");
        }
        System.out.println(temp);
    }

    @Test
    public void test09() throws ClassNotFoundException {
        Class personClass = Class.forName("com.scau.jansing.entities.Person");
        Iterator<Method> methodIterator = Arrays.asList(personClass.getDeclaredMethods()).iterator();
        while(methodIterator.hasNext()){
            Method method = methodIterator.next();
            Annotation[] a = method.getAnnotations();
            for(Annotation aa : a){
                System.out.println(aa);
            }
//            System.out.println(Modifier.toString(method.getModifiers()));
            System.out.println(CommonUtils.getMethodString(method));
        }
    }

    @Test
    public void test10() throws ClassNotFoundException, IOException {
//        System.out.println(Class.class.getClassLoader().getResource("/").getPath());
//        System.out.println(this.getClass().getClassLoader().getResource("/").getPath());


        Class personClass = Class.forName("com.scau.jansing.entities.Person");
        StringBuilder temp = new StringBuilder();

        String path = Class.class.getResource("/").getPath();
        File file = new File(path);
        File app = file.getParentFile().getParentFile();

        temp.append(app.getPath()).append("\\src");
        Iterator<File> fileIterator = Arrays.asList(app.listFiles()).iterator();
        while(fileIterator.hasNext()){
            file = fileIterator.next();
            if(file.getName().equals("pom.xml")){
                temp.append(CommonUtils.MAVEN_EXTRA_PATH);
                file = null;
                break;
            }
        }
        temp.append("\\create")
                .append("\\").append(personClass.getPackage().getName().replaceAll("\\.", "\\\\"))
                .append("\\").append(personClass.getSimpleName()).append(".txt");

        String realPath = temp.toString();
        File javaFile = new File(realPath);
        if(!javaFile.exists()){
            javaFile.getParentFile().mkdirs();
        }

        FileOutputStream output = new FileOutputStream(javaFile);
        output.write(temp.toString().getBytes());
        output.flush();
        output.close();
        System.out.println("the file is : " + realPath);

    }

    @Test
    public void test11() throws ClassNotFoundException, IOException {
        Class personClass = Class.forName("com.scau.jansing.entities.Person");
        FileUtils.outputToFile("fdsafdsafgdsgfsdfdsa", personClass.getTypeName());
    }

    @Test
    public void test12() throws ClassNotFoundException {
        Class personClass = Class.forName("com.scau.jansing.entities.Person");
        String newPackString = "create."+personClass.getPackage().getName()+"."+personClass.getSimpleName();
        System.out.println(newPackString);
    }

    @Test
    public void test13() {
        StringBuilder stringBuilder = new StringBuilder();
        stringBuilder.append("first");
        String first = stringBuilder.toString();
        System.out.println(first);
        stringBuilder.append("");
        String second = stringBuilder.toString();
        System.out.println(second);
        System.out.println(first.equals(second));
    }

    /**
     * result:
     * sb1.append(sb2);<br/>
     * 此后sb2改变不影响sb1
     */
    @Test
    public void validate01(){
        StringBuilder sb1 = new StringBuilder();
        StringBuilder sb2 = new StringBuilder();
        sb2.append("~~~~~~~~");
        sb1.append("1111111").append(sb2).append("2222222");
        System.out.println(sb1);
        sb2.append("@@@@@@");
        System.out.println(sb2);
        System.out.println(sb1);
    }

    /**
     * result:
     * getDeclaredFields() 得到自身声明的属性<br/>
     * getFields() 得到父类、接口声明的属性
     * @throws ClassNotFoundException
     */
    @Test
    public void validate02() throws ClassNotFoundException {
        Class personClass = Class.forName("com.scau.jansing.entities.Person");
        Field[] fs = personClass.getDeclaredFields();
        for(Field f : fs){
            System.out.println(f);
        }

    }
}